-- SdkMgr
-- Created by chengb Nov/21/2015
-- sdk管理器
-- 由于目前SdkMgr的初始化是在UIAutoPatch的构造函数中进行的，这时被require的文件无法自动更新
-- 如果期望文件被更新，需要使用myRequire函数

module("SdkMgr", package.seeall);

local PURE_FILE = "SdkMgr";

-- Object-c回调函数列表
local OCCallbackList = {};

-- 已经require的文件
local requiredFiles = {};

-- 内部函数声明
local handleOCFuncRequest;
local onRechargeOk;
local onRechargeFail;
local onBatchQuerySkuPrice;
local onSendLocPrice;
local onShareImageDownloaded;

-- 初始化
function init()
    assert(type(PUBLISH_PLATFORM) == "string", "必须配置PUBLISH_PLATFORM");

    myRequire("game/sdk/SdkMacros");
    myRequire("game/sdk/SdkAgent");
    myRequire("game/sdk/PurchaseToolkit");

    -- 海外AppStore平台
    if PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE then
        myRequire("game/sdk/ios/BuglyAgent");
        myRequire("game/sdk/ios/GameCenterAgent");
        myRequire("game/sdk/ios/FacebookAgent");
        myRequire("game/sdk/ios/AdwordsAgent");
        myRequire("game/sdk/AppsFlyerAgent");
        myRequire("game/sdk/ios/AppPurchaseAgent");

        -- 初始化 Bugly 代理
        BuglyAgent.init();

        -- 初始化GameCenter代理
        GameCenterAgent.init();

        -- 初始化内购代理
        AppPurchaseAgent.init();

        -- 初始化Facebook代理
        FacebookAgent.init();

        -- 初始化AppsFlyer代理
        AppsFlyerAgent.init();

        -- 初始化 Adwords 代理
        AdwordsAgent.init();

    -- 国内AppStore平台
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE_CN then
        myRequire("game/sdk/ios/BuglyAgent");
        myRequire("game/sdk/ios/GameCenterAgent");
        myRequire("game/sdk/ios/WechatAgent");
        myRequire("game/sdk/ios/WeiboAgent");
        myRequire("game/sdk/ios/AdwordsAgent");
        myRequire("game/sdk/ios/AppPurchaseAgent");

        -- 初始化 Bugly 代理
        BuglyAgent.init();

        -- 初始化GameCenter代理
        GameCenterAgent.init();

        -- 初始化内购代理
        AppPurchaseAgent.init();

        -- 初始化微信代理
        WechatAgent.init();

        -- 初始化微博代理
        WeiboAgent.init();

    -- 雷霆平台
    elseif PUBLISH_PLATFORM == PUBLISH_TYPE_LT then
        myRequire("game/sdk/ios/LeiTingAgent");
        myRequire("game/sdk/ios/BuglyAgent");
        myRequire("game/sdk/ios/GameCenterAgent");
        myRequire("game/sdk/ios/WechatAgent");
        myRequire("game/sdk/ios/WeiboAgent");
        myRequire("game/sdk/ios/AppPurchaseAgent");

        -- 初始化雷霆 SDK 代理
        LeiTingAgent.init();

        -- 初始化 Bugly 代理
        BuglyAgent.init();

        -- 初始化GameCenter代理
        GameCenterAgent.init();

        -- 初始化内购代理
        AppPurchaseAgent.init();

        -- 初始化微信代理
        WechatAgent.init();

        -- 初始化微博代理
        WeiboAgent.init();
    end

    if TALKING_DATA_ENABLED == 1 then
        -- 初始化Talkingdata SDK
        myRequire("game/sdk/TalkingdataAgent");
        TalkingdataAgent.init();
    end

    if HELPSHIFT_ENABLED == 1 then
        -- 初始化Helpshift SDK
        myRequire("game/sdk/ios/HelpshiftAgent");
        HelpshiftAgent.init();
    end

    if isIosPlatform() then
        -- 注册Object-c请求处理器
        callOCFunc("registerScriptHandler",{ scriptHandler = handleOCFuncRequest, });

        -- 通知sdk初始化完毕
        callOCFunc("notifySdkInitOk", { platform = PUBLISH_PLATFORM, });

        -- 注册支付成功的回调
        SdkMgr.registerOCCallback("onRechargeOk", onRechargeOk);

        -- 注册的支付失败的回调
        SdkMgr.registerOCCallback("onRechargeFail", onRechargeFail);

        -- 注册批量查询商品价格的回调
        SdkMgr.registerOCCallback("onBatchQuerySkuPrice", onBatchQuerySkuPrice);

        -- 注册通知本地化价格的回调
        SdkMgr.registerOCCallback("onSendLocPrice", onSendLocPrice);

        -- 注册分享图片下载完成的回调
        SdkMgr.registerOCCallback("onShareImageDownloaded", onShareImageDownloaded);
    end
end

-- 本函数负责require文件并加入到更新队列中
-- 由于目前SdkMgr的初始化是在UIAutoPatch的构造函数中进行的，这时被require的文件无法自动更新
-- 这里将这些文件记录下来，等到自动更新完成后重新update一次
function myRequire(path)
    trace("SdkMgr", "myRequire %s", path);
    require(path);
    table.insert(requiredFiles, path);
end

-- 更新已require的文件
function updateRequiredFiles()
    for _, path in ipairs(requiredFiles) do
        trace("SdkMgr", "update %s", path);
        update(path);
    end
end

-- 查询已require的文件
function queryRequiredFiles()
    trace("SdkMgr", "requiredFiles:%o", requiredFiles);
end

-- 处理所有来至Object-c的请求
handleOCFuncRequest = function(valueDict)
    local funcName = valueDict.func;
    local funcArgs = valueDict.args;

    trace(PURE_FILE, "handleOCFuncRequest:funcName = %s, funcArgs = %s", funcName, funcArgs);

    if OCCallbackList[funcName] then
        OCCallbackList[funcName](funcArgs);
    else
        trace(PURE_FILE, "### 回调(%s)不存在！", funcName);
    end
end

-------------------------
-- 注册Object-c的回调函数
-- @param funcName   回调函数名
-- @param callback   回调函数
function registerOCCallback(funcName, callback)
    assert(type(funcName) == "string", "funcName必须为string类型");
    assert(type(callback) == "function", "callback必须为function类型");

    OCCallbackList[funcName] = callback;
end

-------------------------
-- 移除Object-c回调函数
-- @param funcName 回调函数名
function removeOCCallback(funcName)
    OCCallbackList[funcName] = nil;
end

-- 获取广告标识符
function getIdfa()
    local ret = callOCFunc("getIdfa");
    return ret;
end

-- 获取应用id
function getBundleId()
    return callOCFunc("getBundleId");
end

-- 通知商城载入完毕
function notifyMarketLoaded()
    -- 获取商品sku列表
    local skuList = MarketM.getSkuList();

    -- 将所有sku拼接起来
    local skuStr = "";
    for i, sku in pairs(skuList) do
        skuStr = skuStr .. sku;
        if i < #skuList then
            skuStr = skuStr .. "|";
        end
    end

    -- 获取玩家所在的服务器区组和账号
    local serverId = getCurrentServerId();
    local account =  getGaming3rdAccount();

    local args =  {
        skuStr   = skuStr,
        account  = account,
        serverId = tostring(serverId),
    };

    -- 通知商城加载完毕
    callOCFunc("notifyMarketLoaded", args);
end

-- 通知本地化价格的回调
onSendLocPrice = function(param)
    if param == "" then
        return;
    end

    local resultList = string.explode(param, "|");
    for _, str in pairs(resultList) do
        local arr = string.explode(str, "&");
        local sku   = arr[1];
        local price = arr[2];

        -- TODO 目前中文的'$'和英文版的'￥'显示有问题，故做如下处理
        local lang = getLang();
        if lang == "zh" then
            -- 替换美元符号
            price = changeDollerCharacter(price);
        elseif lang == "en" then
            -- 替换人民币符号
            price = string.gsub(price, "￥", "CNY");
        end

        if sku ~= "" and price ~= "" then
            -- 记录价格
            MarketM.recordSkuPrice(sku, price);
        end
    end
end

-- 充值扣款成功的事件回调（这里只是客户端扣款成功）
function onRechargeOk(param)
    trace("SdkMgr", "onRechargeOk: param = " .. tostring(param));

    local sku;
    local orderId;

    -- 如果是AppStore平台，需要记录订单号
    if PUBLISH_PLATFORM == PUBLISH_TYPE_APP_STORE then
        local info = string.parseJsonToTable(param);
        sku        = info.sku;
        orderId    = info.orderId;
    else
        sku = param;
    end
    ChargeM.rechargeHandle(sku, orderId);
end

-- 充值失败的事件回调
function onRechargeFail(sku)
    EventMgr.fire(event.RECHARGE_FAIL);
end

-- 批量查询商品的回调
function onBatchQuerySkuPrice(param)
    if param == "" then
        return;
    end

    local resultList = string.explode(param, "|");

    for _, str in pairs(resultList) do
        local arr = string.explode(str, "&");
        local sku   = arr[1];
        local price = arr[2];

        -- 如果是国内的平台，需要接上单位
        if not isOverseaPackage() then
            price = price .. getLocStr("yuan");
        else
            -- TODO 目前中文的'$'和英文版的'￥'显示有问题，故做如下处理
            local lang = getLang();
            if lang == "zh" then
                -- 替换美元符号
                price = changeDollerCharacter(price);
            elseif lang == "en" then
                -- 替换人民币符号
                price = string.gsub(price, "￥", "CNY");
            end
        end

        if sku ~= "" and price ~= "" then
            -- 记录价格
            MarketM.recordSkuPrice(sku, price);
        end
    end
end

-- 服务器充值到账的通知
function onServerRechargeOk(sku, serverTime, gem)
    if isIosPlatform() then
        callOCFuncWithClass("IAPWrap", "onServerRechargeOk", {
            sku = sku,
            serverTime = serverTime,
            gem = gem,
        });
    end
end

-- 分享图片下载完成的回调
function onShareImageDownloaded()
    -- 关闭等待中界面
    closeCommunicatingForm();
end

-- TODO 测试OC调用Lua
--[[
local function luaOCTest(args)
    cclog("OC callback execute: args = " .. args);
end

SdkMgr.registerOCCallback("luaOCTest", luaOCTest);
--]]





